<template>
  <div class="set-management">
    <v-card elevation="10">
      <v-card-title>
        <v-icon left>mdi-cog</v-icon>
        系统设置管理
      </v-card-title>

      <v-tabs v-model="activeTab" color="primary" grow>
        <v-tab value="def">
          <v-icon left>mdi-cog-outline</v-icon>
          系统默认
        </v-tab>
        <v-tab value="crypto">
          <v-icon left>mdi-key</v-icon>
          接口加密
        </v-tab>
        <v-tab value="email">
          <v-icon left>mdi-email</v-icon>
          SMTP服务
        </v-tab>
        <v-tab value="storage">
          <v-icon left>mdi-folder-open</v-icon>
          OSS存储服务
        </v-tab>
        <v-tab value="sms">
          <v-icon left>mdi-message-text</v-icon>
          短信服务
        </v-tab>
      </v-tabs>

      <v-card-text>
        <v-window v-model="activeTab">
          <!-- 系统默认配置 -->
          <v-window-item value="def">
            <v-form ref="defFormRef" v-model="defFormValid">
              <v-row>
                <v-col cols="12" md="6">
                  <v-text-field v-model="defFormData.def_pass" label="默认重置密码" :rules="defRules.def_pass" outlined
                    dense />
                </v-col>
              </v-row>

              <v-row>
                <v-col cols="12" md="6">
                  <v-text-field v-model="defFormData.def_role" label="默认角色编号" :rules="defRules.def_role" outlined
                    dense />
                </v-col>
              </v-row>

              <v-row>
                <v-col cols="12" md="6">
                  <v-select v-model="defFormData.storage_type" :items="storageTypeOptions" label="文件存储位置"
                    item-title="dictName" item-value="dictValue" outlined dense />
                </v-col>
              </v-row>

              <v-btn color="primary" :loading="loading" @click="saveConfig('def', defFormData)" class="mt-4">
                保存
              </v-btn>
            </v-form>
          </v-window-item>

          <!-- 接口加密配置 -->
          <v-window-item value="crypto">
            <v-form ref="cryptoFormRef" v-model="cryptoFormValid">
              <v-row>
                <v-col cols="12" md="6">
                  <v-select v-model="cryptoFormData.crypto_asymmetric" :items="cryptoAsymmetricOptions" label="加密算法"
                    item-title="dictName" item-value="dictValue" outlined dense @update:model-value="onCryptoChange" />
                </v-col>
                <v-col cols="12" md="6" class="d-flex align-center">
                  <v-btn color="primary" prepend-icon="mdi-refresh" @click="resetCrypto" :loading="cryptoLoading">
                    重置公私钥
                  </v-btn>
                </v-col>
              </v-row>

              <v-row>
                <v-col cols="12" md="8">
                  <v-text-field v-model="cryptoFormData.crypto_asymmetric_public_key" label="公钥" outlined dense
                    readonly>
                    <template #append>
                      <v-btn icon="mdi-content-copy" size="small"
                        @click="copyToClipboard(cryptoFormData.crypto_asymmetric_public_key)" />
                    </template>
                  </v-text-field>
                </v-col>
              </v-row>

              <v-row>
                <v-col cols="12" md="8">
                  <v-text-field v-model="cryptoFormData.crypto_asymmetric_private_key" label="私钥" outlined dense
                    readonly>
                    <template #append>
                      <v-btn icon="mdi-content-copy" size="small"
                        @click="copyToClipboard(cryptoFormData.crypto_asymmetric_private_key)" />
                    </template>
                  </v-text-field>
                </v-col>
              </v-row>

              <v-btn color="primary" :loading="loading" @click="saveConfig('crypto', cryptoFormData)" class="mt-4">
                保存
              </v-btn>
            </v-form>
          </v-window-item>

          <!-- SMTP服务配置 -->
          <v-window-item value="email">
            <v-tabs v-model="emailTab" color="secondary">
              <v-tab value="config">发信设置</v-tab>
              <v-tab value="test">发信测试</v-tab>
            </v-tabs>

            <v-window v-model="emailTab" class="mt-4">
              <v-window-item value="config">
                <v-form ref="emailFormRef" v-model="emailFormValid">
                  <v-row>
                    <v-col cols="12" md="6">
                      <v-autocomplete v-model="emailFormData.email_smtp" :items="smtpServers" label="SMTP地址" outlined
                        dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="emailFormData.email_port" label="SMTP端口" :rules="emailRules.email_port"
                        outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-select v-model="emailFormData.email_ssl_enable" :items="noYesOptions" label="开启SSL认证"
                        item-title="dictName" item-value="dictValue" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="emailFormData.email_account" label="邮箱账号" :rules="emailRules.email_account"
                        placeholder="*****脱敏存储******" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="emailFormData.email_password" label="邮箱密码" type="password"
                        :rules="emailRules.email_password" placeholder="*****脱敏存储******" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="emailFormData.email_addresser" label="发件人"
                        :rules="emailRules.email_addresser" placeholder="发件人 xxxx@xx.com 或 测试<xxx.xx.com>" outlined
                        dense />
                    </v-col>
                  </v-row>

                  <v-btn color="primary" :loading="loading" @click="saveConfig('email', emailFormData)" class="mt-4">
                    保存
                  </v-btn>
                </v-form>
              </v-window-item>

              <v-window-item value="test">
                <v-form ref="emailTestFormRef" v-model="emailTestFormValid">
                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="emailTestFormData.to" label="收件人" :rules="emailTestRules.to"
                        placeholder="xxxx@xx.com" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="emailTestFormData.subject" label="主题" :rules="emailTestRules.subject"
                        outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-textarea v-model="emailTestFormData.content" label="内容" :rules="emailTestRules.content"
                        outlined dense rows="4" />
                    </v-col>
                  </v-row>

                  <v-btn color="primary" :loading="emailTestLoading" @click="sendTestEmail" class="mt-4">
                    发送邮件
                  </v-btn>
                </v-form>
              </v-window-item>
            </v-window>
          </v-window-item>

          <!-- OSS存储服务配置 -->
          <v-window-item value="storage">
            <v-tabs v-model="storageTab" color="secondary">
              <v-tab value="local">本地配置</v-tab>
              <v-tab value="upyun">又拍云配置</v-tab>
            </v-tabs>

            <v-window v-model="storageTab" class="mt-4">
              <v-window-item value="local">
                <v-form ref="storageLocalFormRef" v-model="storageLocalFormValid">
                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="storageLocalFormData.storage_local_domain" label="域名"
                        placeholder="本地需要到代理名 如 http:xxx.com/opsli-boot" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="storageLocalFormData.storage_local_path_prefix" label="路径前缀"
                        placeholder="路径前缀默认为空" outlined dense />
                    </v-col>
                  </v-row>

                  <v-btn color="primary" :loading="loading" @click="saveConfig('storageLocal', storageLocalFormData)"
                    class="mt-4">
                    保存
                  </v-btn>
                </v-form>
              </v-window-item>

              <v-window-item value="upyun">
                <v-form ref="storageUpyunFormRef" v-model="storageUpyunFormValid">
                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="storageUpyunFormData.storage_upyun_domain" label="域名"
                        placeholder="如 http:xxx.com" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="storageUpyunFormData.storage_upyun_path_prefix" label="路径前缀"
                        placeholder="路径前缀默认为空" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="storageUpyunFormData.storage_upyun_bucket_name" label="仓库名" outlined
                        dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="storageUpyunFormData.storage_upyun_username" label="用户名" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="storageUpyunFormData.storage_upyun_password" label="用户名密码" type="password"
                        placeholder="*****脱敏存储******" outlined dense />
                    </v-col>
                  </v-row>

                  <v-btn color="primary" :loading="loading" @click="saveConfig('storageUpyun', storageUpyunFormData)"
                    class="mt-4">
                    保存
                  </v-btn>
                </v-form>
              </v-window-item>
            </v-window>
          </v-window-item>

          <!-- 短信服务配置 -->
          <v-window-item value="sms">
            <v-tabs v-model="smsTab" color="secondary">
              <v-tab value="aliyun">阿里云短信</v-tab>
            </v-tabs>

            <v-window v-model="smsTab" class="mt-4">
              <v-window-item value="aliyun">
                <v-form ref="smsAliyunFormRef" v-model="smsAliyunFormValid">
                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="smsAliyunFormData.sms_aliyun_access_key" label="AccessKey"
                        :rules="smsAliyunRules.sms_aliyun_access_key" placeholder="AccessKey" outlined dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="smsAliyunFormData.sms_aliyun_access_key_secret" label="AccessKeySecret"
                        :rules="smsAliyunRules.sms_aliyun_access_key_secret" placeholder="******脱敏存储******" outlined
                        dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="smsAliyunFormData.sms_aliyun_captcha_template_code" label="验证码模版"
                        :rules="smsAliyunRules.sms_aliyun_captcha_template_code" placeholder="请输入验证码短信模版" outlined
                        dense />
                    </v-col>
                  </v-row>

                  <v-row>
                    <v-col cols="12" md="6">
                      <v-text-field v-model="smsAliyunFormData.sms_aliyun_captcha_sign" label="验证码签名"
                        :rules="smsAliyunRules.sms_aliyun_captcha_sign" placeholder="请输入验证码签名" outlined dense />
                    </v-col>
                  </v-row>

                  <v-btn color="primary" :loading="loading" @click="saveConfig('smsAliyun', smsAliyunFormData)"
                    class="mt-4">
                    保存
                  </v-btn>
                </v-form>
              </v-window-item>
            </v-window>
          </v-window-item>
        </v-window>
      </v-card-text>
    </v-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { useMessage } from '@/composables/useMessage'
import { useDict } from '@/composables/useDict'
import {
  getAllOptions,
  doCreateCrypto,
  doUpdateOptions,
  doTestSend,
} from '@/api/system/set/setManagement'

// 消息提示
const { show: showMessage } = useMessage()

// 字典
const { getDictList } = useDict()

// 响应式数据
const activeTab = ref('def')
const emailTab = ref('config')
const storageTab = ref('local')
const smsTab = ref('aliyun')

const loading = ref(false)
const cryptoLoading = ref(false)
const emailTestLoading = ref(false)

// 表单验证状态
const defFormValid = ref(false)
const cryptoFormValid = ref(false)
const emailFormValid = ref(false)
const emailTestFormValid = ref(false)
const storageLocalFormValid = ref(false)
const storageUpyunFormValid = ref(false)
const smsAliyunFormValid = ref(false)

// 表单引用
const defFormRef = ref()
const cryptoFormRef = ref()
const emailFormRef = ref()
const emailTestFormRef = ref()
const storageLocalFormRef = ref()
const storageUpyunFormRef = ref()
const smsAliyunFormRef = ref()

// 字典选项
const noYesOptions = ref<any[]>([])
const storageTypeOptions = ref<any[]>([])
const cryptoAsymmetricOptions = ref<any[]>([])

// SMTP服务器列表
const smtpServers = [
  'smtp.aliyun.com',
  'smtp.gmail.com',
  'smtp.sina.com.cn',
  'smtp.tom.com',
  'smtp.163.com',
  'smtp.126.com',
  'smtp.mail.yahoo.com',
  'smtp.mail.yahoo.com.cn',
  'smtp.foxmail.com',
  'smtp.foxmail.com.cn',
  'smtp.qq.com',
  'smtp.sohu.com',
  'smtp.live.com',
  'smtp.139.com',
  'smtp.china.com'
]

// 表单数据
const defFormData = reactive({
  def_pass: '',
  def_role: '',
  storage_type: 'local'
})

const cryptoFormData = reactive({
  crypto_asymmetric: '',
  crypto_asymmetric_public_key: '',
  crypto_asymmetric_private_key: ''
})

const emailFormData = reactive({
  email_smtp: '',
  email_port: '',
  email_ssl_enable: '1',
  email_account: '',
  email_password: '',
  email_addresser: ''
})

const emailTestFormData = reactive({
  to: '1224299352@qq.com',
  subject: '你好',
  content: '你好'
})

const storageLocalFormData = reactive({
  storage_local_domain: '',
  storage_local_path_prefix: ''
})

const storageUpyunFormData = reactive({
  storage_upyun_domain: '',
  storage_upyun_path_prefix: '',
  storage_upyun_bucket_name: '',
  storage_upyun_username: '',
  storage_upyun_password: ''
})

const smsAliyunFormData = reactive({
  sms_aliyun_access_key: '',
  sms_aliyun_access_key_secret: '',
  sms_aliyun_captcha_template_code: '',
  sms_aliyun_captcha_sign: ''
})

// 验证规则
const defRules = {
  def_pass: [
    (v: string) => !!v || '请输入默认密码'
  ],
  def_role: [
    (v: string) => !!v || '请输入默认角色编号'
  ]
}

const emailRules = {
  email_smtp: [
    (v: string) => !!v || '请输入SMTP地址'
  ],
  email_port: [
    (v: string) => !!v || '请输入SMTP端口'
  ],
  email_account: [
    (v: string) => !!v || '请输入邮箱账号'
  ],
  email_password: [
    (v: string) => !!v || '请输入邮箱密码'
  ],
  email_addresser: [
    (v: string) => !!v || '请输入发件人'
  ]
}

const emailTestRules = {
  to: [
    (v: string) => !!v || '请输入收件人',
    (v: string) => /.+@.+\..+/.test(v) || '请输入有效的邮箱地址'
  ],
  subject: [
    (v: string) => !!v || '请输入主题'
  ],
  content: [
    (v: string) => !!v || '请输入内容'
  ]
}

const smsAliyunRules = {
  sms_aliyun_access_key: [
    (v: string) => !!v || '请输入AccessKey'
  ],
  sms_aliyun_access_key_secret: [
    (v: string) => !!v || '请输入AccessKeySecret'
  ],
  sms_aliyun_captcha_template_code: [
    (v: string) => !!v || '请输入验证码短信模版编号'
  ],
  sms_aliyun_captcha_sign: [
    (v: string) => !!v || '请输入验证码短信签名'
  ]
}

// 方法
const loadDictionaries = async () => {
  try {
    noYesOptions.value = await getDictList('no_yes')
    storageTypeOptions.value = await getDictList('storage_type')
    cryptoAsymmetricOptions.value = await getDictList('crypto_asymmetric')
  } catch (error) {
    showMessage('加载字典数据失败', 'error')
  }
}

const fetchData = async () => {
  try {
    loading.value = true
    let { data } = await getAllOptions({})
    if (data) {
      // 系统默认配置
      defFormData.def_pass = data.def_pass?.optionValue || ''
      defFormData.def_role = data.def_role?.optionValue || ''
      defFormData.storage_type = data.storage_type?.optionValue || 'local'

      // 接口加密数据
      cryptoFormData.crypto_asymmetric = data.crypto_asymmetric?.optionValue || ''
      cryptoFormData.crypto_asymmetric_public_key = data.crypto_asymmetric_public_key?.optionValue || ''
      cryptoFormData.crypto_asymmetric_private_key = data.crypto_asymmetric_private_key?.optionValue || ''

      // 邮箱配置
      emailFormData.email_smtp = data.email_smtp?.optionValue || ''
      emailFormData.email_port = data.email_port?.optionValue || ''
      emailFormData.email_ssl_enable = data.email_ssl_enable?.optionValue || '1'
      emailFormData.email_addresser = data.email_addresser?.optionValue || ''

      // 本地存储
      storageLocalFormData.storage_local_domain = data.storage_local_domain?.optionValue || ''
      storageLocalFormData.storage_local_path_prefix = data.storage_local_path_prefix?.optionValue || ''

      // 又拍云存储
      storageUpyunFormData.storage_upyun_domain = data.storage_upyun_domain?.optionValue || ''
      storageUpyunFormData.storage_upyun_path_prefix = data.storage_upyun_path_prefix?.optionValue || ''
      storageUpyunFormData.storage_upyun_bucket_name = data.storage_upyun_bucket_name?.optionValue || ''
      storageUpyunFormData.storage_upyun_username = data.storage_upyun_username?.optionValue || ''

      // 阿里云短信
      smsAliyunFormData.sms_aliyun_access_key = data.sms_aliyun_access_key?.optionValue || ''
      smsAliyunFormData.sms_aliyun_captcha_template_code = data.sms_aliyun_captcha_template_code?.optionValue || ''
      smsAliyunFormData.sms_aliyun_captcha_sign = data.sms_aliyun_captcha_sign?.optionValue || ''
    }
  } catch (error) {
    showMessage('获取配置数据失败', 'error')
  } finally {
    loading.value = false
  }
}

const onCryptoChange = () => {
  cryptoFormData.crypto_asymmetric_public_key = ''
  cryptoFormData.crypto_asymmetric_private_key = ''
}

const resetCrypto = async () => {
  if (!cryptoFormData.crypto_asymmetric) {
    showMessage('请先选择加密算法', 'warning')
    return
  }

  try {
    cryptoLoading.value = true
    const { data } = await doCreateCrypto(cryptoFormData.crypto_asymmetric)

    if (data) {
      cryptoFormData.crypto_asymmetric_public_key = data.publicKey
      cryptoFormData.crypto_asymmetric_private_key = data.privateKey
      showMessage('已重置公私钥，保存后生效', 'warning')
    }
  } catch (error) {
    showMessage('重置公私钥失败', 'error')
  } finally {
    cryptoLoading.value = false
  }
}

const copyToClipboard = async (text: string) => {
  try {
    await navigator.clipboard.writeText(text)
    showMessage('复制成功', 'success')
  } catch (error) {
    showMessage('复制失败', 'error')
  }
}

const saveConfig = async (type: string, formData: any) => {
  const formRefs: Record<string, any> = {
    def: defFormRef,
    crypto: cryptoFormRef,
    email: emailFormRef,
    storageLocal: storageLocalFormRef,
    storageUpyun: storageUpyunFormRef,
    smsAliyun: smsAliyunFormRef
  }

  const formRef = formRefs[type]
  if (!formRef?.value) return

  const { valid } = await formRef.value.validate()
  if (!valid) return

  try {
    loading.value = true
    const response = await doUpdateOptions(formData)
    const msg = (response as any)?.msg || '保存成功'
    showMessage(msg, 'success')
  } catch (error) {
    showMessage('保存失败', 'error')
  } finally {
    loading.value = false
  }
}

const sendTestEmail = async () => {
  if (!emailTestFormRef.value) return

  const { valid } = await emailTestFormRef.value.validate()
  if (!valid) return

  try {
    emailTestLoading.value = true
    const response = await doTestSend(emailTestFormData)
    const msg = (response as any)?.msg || '邮件发送成功'
    showMessage(msg, 'success')
  } catch (error) {
    showMessage('邮件发送失败', 'error')
  } finally {
    emailTestLoading.value = false
  }
}

// 生命周期
onMounted(async () => {
  await loadDictionaries()
  await fetchData()
})
</script>

<style scoped>
.set-management {
  padding: 20px;
}

.v-window-item {
  padding: 20px 0;
}
</style>
